/*******************************************************************************
*
*	模块名称 :  IO
*
*******************************************************************************/
#define PORT_PIN_CTEAT
#include "bsp.h"
#include "iohandle.h" 
#include "pincfg.h"


/*******************************************************************************
* @brief  bsp_gpio_init
* \param[in] us delay
* \retval: none
*******************************************************************************/
void bsp_gpio_init(void)
{
    /*gpio cfg*/
    PA->MODE = 0xFFFFFFFF;
    PB->MODE = 0xFFFFFFFF;
    PC->MODE = 0xFFFFFFFF;
    PD->MODE = 0xFFFFFFFF;
    PE->MODE = 0xFFFFFFFF;
    PF->MODE = 0xFFFFFFFF;
    PG->MODE = 0xFFFFFFFF;
    PH->MODE = 0xFFFFFFFF;
    
    //LED MODE
    GPIO_SetMode(PB, BIT15, GPIO_MODE_OUTPUT);
    GPIO_SetMode(PC, BIT14, GPIO_MODE_OUTPUT);
    //QPI CS
    GPIO_SetMode(PA, BIT3 | BIT7, GPIO_MODE_OUTPUT);
    PA3 = 1;
    PA7 = 1;
    //U2 U4 U0 TD
    gpio_mode_set(PF, 6, GPIO_MODE_OUTPUT);
    gpio_mode_set(PB, 13, GPIO_MODE_OUTPUT);
    gpio_mode_set(PB, 14, GPIO_MODE_OUTPUT);
	
    PF6 = 0;
    PB13 = 0;
    PB14 = 0;
    
    //pin input enable
    PA->DINOFF = 0;
    PB->DINOFF = 0;
    PC->DINOFF = 0;
    PD->DINOFF = 0;
    PE->DINOFF = 0;
    PF->DINOFF = 0;
    PG->DINOFF = 0;
    PH->DINOFF = 0;
    
    /* Set GPB multi-function pins for UART0 UART4 RXD and TXD  */
	bsp_pin_mfp_set(PB, 8, SYS_GPB_MFPH_PB8MFP_UART0_RXD);
	bsp_pin_mfp_set(PB, 9, SYS_GPB_MFPH_PB9MFP_UART0_TXD);
	bsp_pin_mfp_set(PB, 10, SYS_GPB_MFPH_PB10MFP_UART4_RXD);
	bsp_pin_mfp_set(PB, 11, SYS_GPB_MFPH_PB11MFP_UART4_TXD);

    /* Set GPF multi-function pins for UART2 RXD and TXD */
    bsp_pin_mfp_set(PF, 4, SYS_GPF_MFPL_PF4MFP_UART2_TXD);
	bsp_pin_mfp_set(PF, 5, SYS_GPF_MFPL_PF5MFP_UART2_RXD);

	/* SPI */
	bsp_pin_mfp_set(PC, 1, SYS_GPC_MFPL_PC1MFP_SPI1_CLK);
	bsp_pin_mfp_set(PC, 2, SYS_GPC_MFPL_PC2MFP_SPI1_MOSI);
	bsp_pin_mfp_set(PC, 3, SYS_GPC_MFPL_PC3MFP_SPI1_MISO);
	spi1_ss.dir_out_pp();
	spi1_ss.en();
	
	/* I2S*/
	bsp_pin_mfp_set(PB, 5, SYS_GPB_MFPL_PB5MFP_I2S0_BCLK);	// 位时钟
	bsp_pin_mfp_set(PB, 4, SYS_GPB_MFPL_PB4MFP_I2S0_MCLK);	// 主时钟
	bsp_pin_mfp_set(PB, 3, SYS_GPB_MFPL_PB3MFP_I2S0_DI);	// 数据输入
	bsp_pin_mfp_set(PB, 2, SYS_GPB_MFPL_PB2MFP_I2S0_DO);	// 数据输出
	bsp_pin_mfp_set(PB, 1, SYS_GPB_MFPL_PB1MFP_I2S0_LRCK);	// 左右声道
	
	/* QPI */
	bsp_qpi_port_init();
	
	/* SDIO */
	bsp_pin_mfp_set(PA, 8, SYS_GPA_MFPH_PA8MFP_SD1_DAT0);
	bsp_pin_mfp_set(PA, 9, SYS_GPA_MFPH_PA9MFP_SD1_DAT1);
	bsp_pin_mfp_set(PA, 10, SYS_GPA_MFPH_PA10MFP_SD1_DAT2);
	bsp_pin_mfp_set(PA, 11, SYS_GPA_MFPH_PA11MFP_SD1_DAT3);
	bsp_pin_mfp_set(PB, 6, SYS_GPB_MFPL_PB6MFP_SD1_CLK);
	bsp_pin_mfp_set(PB, 7, SYS_GPB_MFPL_PB7MFP_SD1_CMD);
	bsp_pin_mfp_set(PA, 6, SYS_GPA_MFPL_PA6MFP_SD1_nCD);
	
    /* Enable QSPI0 clock pin (PA2) schmitt trigger */
    PA->SMTEN |= GPIO_SMTEN_SMTEN2_Msk;

    /* Enable QSPI0 I/O high slew rate */
    GPIO_SetSlewCtl(PA, 0x3F, GPIO_SLEWCTL_HIGH);
	
	/* Enable SDH1 I/O high slew rate */
    GPIO_SetSlewCtl(PA, 0x0FUL << 8, GPIO_SLEWCTL_HIGH);
	GPIO_SetSlewCtl(PB, 0x03UL << 6, GPIO_SLEWCTL_HIGH);
}

/*******************************************************************************
* @brief  bsp_gpio
* \param[in] none
* \retval: none
*******************************************************************************/
void bsp_qpi_port_init(void)
{
	uint32_t msk, sel;

	intx_alloc();
	
	intx_disable();
	
	msk = SYS_GPA_MFPL_PA0MFP_Msk | SYS_GPA_MFPL_PA1MFP_Msk
		| SYS_GPA_MFPL_PA2MFP_Msk | SYS_GPA_MFPL_PA3MFP_Msk
		| SYS_GPA_MFPL_PA4MFP_Msk | SYS_GPA_MFPL_PA5MFP_Msk
		| SYS_GPA_MFPL_PA7MFP_Msk;
	
	sel = SYS_GPA_MFPL_PA0MFP_QSPI0_MOSI0 | SYS_GPA_MFPL_PA1MFP_QSPI0_MISO0
		| SYS_GPA_MFPL_PA4MFP_QSPI0_MOSI1 | SYS_GPA_MFPL_PA5MFP_QSPI0_MISO1
		| SYS_GPA_MFPL_PA2MFP_QSPI0_CLK
		| SYS_GPA_MFPL_PA3MFP_GPIO | SYS_GPA_MFPL_PA7MFP_GPIO;
	
    /* Setup QSPI0 multi-function pins */
    SYS->GPA_MFPL &= ~msk;  
    SYS->GPA_MFPL |=  sel;
	
	PA3 = 1;	// nor  ss
	PA7 = 1;	// nand ss
	
	SYS_UnlockReg(); 
	SPIM_SET_OPMODE(SPIM_CTL0_OPMODE_IO);
	SYS_LockReg(); 
	
	intx_enable();                 
}

void bsp_spim_port_init(void)
{
	uint32_t msk, sel;
	
	intx_alloc();
	
	intx_disable();
	
	msk = SYS_GPA_MFPL_PA0MFP_Msk | SYS_GPA_MFPL_PA1MFP_Msk
		| SYS_GPA_MFPL_PA2MFP_Msk | SYS_GPA_MFPL_PA3MFP_Msk
		| SYS_GPA_MFPL_PA4MFP_Msk | SYS_GPA_MFPL_PA5MFP_Msk
		| SYS_GPA_MFPL_PA7MFP_Msk;
	
	sel = SYS_GPA_MFPL_PA0MFP_SPIM_MOSI | SYS_GPA_MFPL_PA1MFP_SPIM_MISO
		| SYS_GPA_MFPL_PA4MFP_SPIM_D3 | SYS_GPA_MFPL_PA5MFP_SPIM_D2
		| SYS_GPA_MFPL_PA2MFP_SPIM_CLK
		| SYS_GPA_MFPL_PA3MFP_SPIM_SS | SYS_GPA_MFPL_PA7MFP_GPIO;
	
    /* Setup QSPI0 multi-function pins */
    SYS->GPA_MFPL &= ~msk;  
    SYS->GPA_MFPL |=  sel;
	
	PA7 = 1;	// nand ss
	
	intx_enable(); 
}


/*******************************************************************************
* @brief  bsp_gpio
* \param[in] port pin
* \retval: none
*******************************************************************************/
void bsp_gpio_mode_out_pp(GPIO_T * port, uint8_t pin)
{
	intx_alloc();
	
	intx_disable();
		
	gpio_mode_set(port, pin, GPIO_MODE_OUTPUT);
	
	intx_enable();
}

void bsp_gpio_mode_out_od(GPIO_T * port, uint8_t pin)
{
	intx_alloc();
	
	intx_disable();
	
	gpio_mode_set(port, pin, GPIO_MODE_OPEN_DRAIN);
	
	intx_enable();
}

void bsp_gpio_mode_in_up(GPIO_T * port, uint8_t pin)
{
	intx_alloc();
	
	intx_disable();
	
	gpio_mode_set(port, pin, GPIO_MODE_QUASI);
	port->DOUT |= 1UL << pin;
	
	intx_enable();
}

void bsp_gpio_mode_in_dn(GPIO_T * port, uint8_t pin)
{
	intx_alloc();
	
	intx_disable();
	
	gpio_mode_set(port, pin, GPIO_MODE_QUASI);
	port->DOUT |= 1UL << pin;
	
	intx_enable();
}


void bsp_gpio_mode_in_ft(GPIO_T * port, uint8_t pin)
{
	intx_alloc();
	
	intx_disable();
	
	gpio_mode_set(port, pin, GPIO_MODE_INPUT);
	
	intx_enable();
}

/*******************************************************************************
* @brief  bsp_gpio
* \param[in] port pin
* \retval: none
*******************************************************************************/
void bsp_pin_mfp_set(GPIO_T * port, uint8_t pin, uint32_t  fun)
{
	uint32_t msk = ~(0x0FUL << ( (pin & 0x07) << 2 ));
	
	switch((uint32_t)port)
	{
		case GPIOA_BASE:
		{
			if(pin <= 7)
				SYS->GPA_MFPL = (SYS->GPA_MFPL & msk) | fun;
			else
				SYS->GPA_MFPH = (SYS->GPA_MFPH & msk) | fun;
			break;
		}
		case GPIOB_BASE:
		{
			if(pin <= 7)
				SYS->GPB_MFPL = (SYS->GPB_MFPL & msk) | fun;
			else
				SYS->GPB_MFPH = (SYS->GPB_MFPH & msk) | fun;
			break;
		}
		case GPIOC_BASE:
		{
			if(pin <= 7)
				SYS->GPC_MFPL = (SYS->GPC_MFPL & msk) | fun;
			else
				SYS->GPC_MFPH = (SYS->GPC_MFPH & msk) | fun;
			break;
		}
		case GPIOD_BASE:
		{
			if(pin <= 7)
				SYS->GPD_MFPL = (SYS->GPD_MFPL & msk) | fun;
			else
				SYS->GPD_MFPH = (SYS->GPD_MFPH & msk) | fun;
			break;
		}
		case GPIOE_BASE:
		{
			if(pin <= 7)
				SYS->GPE_MFPL = (SYS->GPE_MFPL & msk) | fun;
			else
				SYS->GPE_MFPH = (SYS->GPE_MFPH & msk) | fun;
			break;
		}
		case GPIOF_BASE:
		{
			if(pin <= 7)
				SYS->GPF_MFPL = (SYS->GPF_MFPL & msk) | fun;
			else
				SYS->GPF_MFPH = (SYS->GPF_MFPH & msk) | fun;
			break;
		}
		case GPIOG_BASE:
		{
			if(pin <= 7)
				SYS->GPG_MFPL = (SYS->GPG_MFPL & msk) | fun;
			else
				SYS->GPG_MFPH = (SYS->GPG_MFPH & msk) | fun;
			break;
		}
		case GPIOH_BASE:
		{
			if(pin <= 7)
				SYS->GPH_MFPL = (SYS->GPH_MFPL & msk) | fun;
			else
				SYS->GPH_MFPH = (SYS->GPH_MFPH & msk) | fun;
			break;
		}
		default:
			break;
	}
}
